package com.tpp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.tpp.client.EmailClients;
import com.tpp.client.InformationClients;
import com.tpp.dao.UserRepository;
import com.tpp.pojo.TppUser;
import com.tpp.pojo.baseVo.BaseResult;
import com.tpp.pojo.req.TppUserReq;
import com.tpp.service.UserService;
import com.tpp.utils.JwtUtils;
import com.tpp.utils.MD5Util;
import com.tpp.utils.RedisUtils;
import com.tpp.utils.UploadUtils;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserRepository userRepository;
    @Autowired
    EmailClients emailClients;
    @Autowired
    InformationClients informationClients;
    @Autowired
    RedisUtils redisUtils;

    /**
     * 注册时检验邮箱
     * @param email
     * @return
     */
    @Override
    public BaseResult validataEmail(String email) {
        //查询从前端传来的邮箱是否为空
        if (email == null){
            return new BaseResult(1,"邮箱不能为空");
        }

        //去数据库查询前端传来的邮箱是否存在
        TppUser byEmail = userRepository.findByEmail(email);
        if (byEmail != null ){
            return new BaseResult(1,"此邮箱已被注册");
        }

        return new BaseResult(0,"邮箱未被占用");
    }

    @Override
    public BaseResult validataPhone(String phone) {
        //查询从前端传来的手机号是否为空
        if (phone == null){
            return new BaseResult(1,"手机号不能为空");
        }

        //去数据库查询前端传来的手机号是否存在
        TppUser byPhone = userRepository.findByPhone(phone);
        if (byPhone != null){
            return new BaseResult(1,"此手机号已被注册");
        }

        return new BaseResult(0,"手机号未被占用");
    }



    @Override
    public BaseResult validataloginName(Map map) {
        Object username = map.get("username");
        System.out.println(username.toString());
        //判断登录名是否为空
        if(username==null){
            return new BaseResult(1,"用户名不能为空");
        }
        TppUser byUserName = userRepository.findByUserName(username.toString());
        System.out.println(byUserName);
        if(byUserName != null){
            return new BaseResult(1,"用户名已存在");
        }
        return new BaseResult(0,"用户名可以注册");
    }

    @Autowired
    RabbitTemplate rabbitTemplate;
    @Override
    public BaseResult sendMail(String email) {

        Map map = new HashMap();
        map.put("email",email);
        rabbitTemplate.convertAndSend("","tpp-cloud-mail",map);
        return new BaseResult(0,"发送成功！");

    }

    @Override
    public BaseResult sendInformation(String phone) {
        Map map = new HashMap();
        map.put("phone",phone);
       // Boolean aBoolean = informationClients.getCode(map);
        rabbitTemplate.convertAndSend("","tpp-cloud-information",map);

            return new BaseResult(0,"发送成功!");

    }

    @Override
    public BaseResult registry(TppUserReq tppUserReq) {

        System.out.println("邮箱号"+tppUserReq.getEmail());
        System.out.println("手机号"+tppUserReq.getPhone());
        System.out.println("用户名"+tppUserReq.getUserName());

        TppUser byLoginName = userRepository.findByUserName(tppUserReq.getUserName());
//        判断用户名是否存在
        if (byLoginName!=null){
            return new BaseResult(1,"用户名已被注册！");
        }
//       用户名不存在时,判断邮箱是否为空或空字符串
//        邮箱为空时
        if (tppUserReq.getEmail()==null||tppUserReq.getEmail()==""){
//            判断手机号是否为空
            if (tppUserReq.getPhone()==null){
                return new BaseResult(1,"请输入手机号!");
            }
//            验证手机号在数据库中是否存在
            TppUser byPhone = userRepository.findByPhone(tppUserReq.getPhone());
//            如果存在
            if(byPhone!=null){
                return new BaseResult(1,"手机号已被注册");
            }
//            如果不存在,判断手机验证码是否失效
            boolean b1 = redisUtils.hasKey(tppUserReq.getPhone());
//            如果失效
            if(!b1){
                return new BaseResult(1,"手机验证码失效！");
            }
//            如果不失效判断手机验证码是否错误
            Object o1 = redisUtils.get(tppUserReq.getPhone());
//            如果错误
            if(!tppUserReq.getIncode().equals(o1.toString())){
                return new BaseResult(1,"手机验证码错误！");
            }
            //如果手机验证码正确,去添加到数据库
            TppUser tppUser = new TppUser();
            BeanUtils.copyProperties(tppUserReq,tppUser);

            tppUser.setPhone(tppUserReq.getPhone());
            tppUser.setUserName(tppUserReq.getUserName());
            //md5密码的加密
            tppUser.setPassword(MD5Util.getStringMD5(tppUserReq.getPassword()));
            userRepository.saveAndFlush(tppUser);
            return new BaseResult(0,"注册成功！",tppUser);

        }
//       邮箱不为空时
        else{
//            判断数据库是否存在该邮箱
            TppUser byEmail = userRepository.findByEmail(tppUserReq.getEmail());
//            数据库存在该邮箱时
            if (byEmail!=null){
                return new BaseResult(1,"邮箱号已被注册！");
            }
//            数据库不存在该邮箱时，判断邮箱验证码是否失效
//            邮箱验证码失效时

            boolean b = redisUtils.hasKey(tppUserReq.getEmail());
            if (!b){
                return new BaseResult(1,"邮箱验证码失效！");
            }
//            邮箱验证码未失效时，判断邮箱验证码是否错误
//            邮箱验证码错误时
            Object o = redisUtils.get(tppUserReq.getEmail());
            if (!tppUserReq.getCode().equals(o.toString())){
                return new BaseResult(1,"邮箱验证码错误！");
            }
            //            邮箱验证码正确时
//            把邮箱号、用户名、密码（加密）保存到数据库中
            TppUser tppUser = new TppUser();
            BeanUtils.copyProperties(tppUserReq,tppUser);

            tppUser.setEmail(tppUserReq.getEmail());
            tppUser.setUserName(tppUserReq.getUserName());
            //md5密码的加密
            tppUser.setPassword(MD5Util.getStringMD5(tppUser.getPassword()));
            userRepository.saveAndFlush(tppUser);
            return new BaseResult(0,"注册成功！",tppUser);

        }


    }

    @Override
    public BaseResult login(TppUserReq tbUserReq) {
        //1.通过用户名查询
        TppUser tppUser = userRepository.findByUserName(tbUserReq.getUserName());
        if (tppUser==null){
            return new BaseResult(1,"请先注册！");
        }
        String password = tbUserReq.getPassword();
        if (!tppUser.getPassword().equals(MD5Util.getStringMD5(password))){
            return new BaseResult(1,"密码错误");
        }
        //如果都没问题，进行登录操作 生成jwt 同时放入redis中
        JwtUtils jwtUtils = new JwtUtils();
        String jsonuser = jwtUtils.SignToken(JSONObject.toJSONString(tppUser));
        //放置在redis中
        String token = UUID.randomUUID().toString();
        //将 jsonuser 为vale放置在redis中
        redisUtils.set(token,jsonuser);
        return new BaseResult(0,"登录成功",token);
    }

    @Override
    public BaseResult findUserByToken(HttpServletRequest request) {
        //1、获取header中的token
        String token = request.getHeader("token");
        //2、验证redis
        boolean b = redisUtils.hasKey(token);
        if (!b){
            return new BaseResult(1,"用户信息已过期");
        }
        String jwtToken = redisUtils.get(token).toString();
        JwtUtils jwtUtils = new JwtUtils();
        String s = jwtUtils.VerifyToekn(jwtToken);
        //从json转为实体
        TppUser tppUser = JSONObject.parseObject(s, TppUser.class);
        return new BaseResult(0,"查询成功",tppUser);
    }

    @Override
    public BaseResult loginOut(HttpServletRequest request) {
        //1、获取header中的token
        String token = request.getHeader("token");
        //2、验证redis
        boolean b = redisUtils.hasKey(token);
        if(!b){
            return new BaseResult(1,"用户信息已过期");
        }
        redisUtils.del(token);
        return new BaseResult(0,"退出成功");
    }

    @Override
    public BaseResult updateUser(TppUserReq tppUserReq, HttpServletRequest request) {
//        1.确定手机号唯一性
        TppUser tbUser = userRepository.findByPhone(tppUserReq.getPhone());
        if (tbUser!=null){
            return new BaseResult(1,"手机号已被绑定");
        }
        //从token中解析出用户对象
        //1.获取header中的token
        String token = request.getHeader("token");
        System.out.println(token);
        //2.验证redis
        boolean b = redisUtils.hasKey(token);
        System.out.println(b);
        if (!b){
            return new BaseResult(1,"用户信息已过期");
        }
        String jwtToken = redisUtils.get(token).toString();
        JwtUtils jwtUtils = new JwtUtils();
        String s = jwtUtils.VerifyToekn(jwtToken);
        //从json转为实体
        TppUser user = JSONObject.parseObject(s, TppUser.class);
        //赋值
        user.setUserName(tppUserReq.getUserName());
        user.setEmail(tppUserReq.getEmail());
        user.setPhone(tppUserReq.getPhone());
        user.setSex(tppUserReq.getSex());
        user.setBirthday(tppUserReq.getBirthday());

        user.setImage(tppUserReq.getImage());

//        user.setAddress((tppUserReq.getAddress()));
        //修改
        TppUser tppUser1 = userRepository.saveAndFlush(user);
        //修改token中的数据
        String s1 = jwtUtils.SignToken(JSONObject.toJSONString(tppUser1));
        redisUtils.set(token,s1);
        return new BaseResult(0,"修改成功",tppUser1);
    }

    @Override
    public BaseResult updatePassword(TppUserReq tppUserReq, HttpServletRequest request) {

        //从token中解析出用户对象
        //1.获取header中的token
        String token = request.getHeader("token");
        System.out.println(token);
        //2.验证redis
        boolean b = redisUtils.hasKey(token);
        System.out.println(b);
        if (!b){
            return new BaseResult(1,"用户信息已过期");
        }
        String jwtToken = redisUtils.get(token).toString();
        JwtUtils jwtUtils = new JwtUtils();
        String s = jwtUtils.VerifyToekn(jwtToken);
        //从json转为实体
        TppUser user = JSONObject.parseObject(s, TppUser.class);

        //      旧密码
        String password = tppUserReq.getPassword();
//        把旧密码进行加密
        String stringMD5Password = MD5Util.getStringMD5(password);
//        对旧密码与数据库的数据进行验证比对
        if (!stringMD5Password.equals(user.getPassword())){
            return new BaseResult(1,"旧密码验证失败");
        }

        //赋值
//        getNewPassword为前端传来的新密码
        user.setPassword(MD5Util.getStringMD5(tppUserReq.getNewPassword()));
        //修改
        TppUser tppUser1 = userRepository.saveAndFlush(user);
        //修改token中的数据
        String s1 = jwtUtils.SignToken(JSONObject.toJSONString(tppUser1));
        redisUtils.set(token,s1);
        return new BaseResult(0,"密码修改成功",tppUser1);
    }

    @Override
    public BaseResult verigyMail(TppUserReq tppUserReq) {
        String email = tppUserReq.getEmail();
        if (email == null){
            return new BaseResult(1,"请输入邮箱");
        }
        TppUser byEmail = userRepository.findByEmail(email);
        if (byEmail==null){
            return new BaseResult(1,"请输入您注册时的邮箱");
        }
        boolean b = redisUtils.hasKey(tppUserReq.getEmail());
        if (!b){
            return new BaseResult(1,"你的邮箱验证码已失效,请重新发送");
        }
        Object o = redisUtils.get(tppUserReq.getEmail());
        if (!tppUserReq.getCode().equals(o.toString())){
            return new BaseResult(1,"您输入的验证码有误");
        }
        return new BaseResult(0,"您的身份验证成功");
    }

    @Override
    public BaseResult verigyPhone(TppUserReq tppUserReq) {
        String phone = tppUserReq.getPhone();
        if (phone == null){
            return new BaseResult(1,"请输入手机号");
        }
        TppUser byphone = userRepository.findByPhone(phone);
        if (byphone==null){
            return new BaseResult(1,"请输入您正确的注册时手机号");
        }
        boolean b = redisUtils.hasKey(tppUserReq.getPhone());
        if (!b){
            return new BaseResult(1,"你的手机验证码已失效,请重新发送");
        }
        Object o = redisUtils.get(tppUserReq.getPhone());
        if (!tppUserReq.getIncode().equals(o.toString())){
            return new BaseResult(1,"您输入的验证码有误");
        }

        return new BaseResult(0,"您的身份验证成功");
    }

    @Override
    public BaseResult updatePassword2(TppUserReq tppUserReq) {


        String newPassword = tppUserReq.getNewPassword();

        return null;
    }


    @Override
    public BaseResult upload(MultipartFile file) {
        UploadUtils uploadUtils = new UploadUtils();
        try {
            String upload = uploadUtils.upload(file.getInputStream());
            System.out.println("upload" + upload);
            return new BaseResult(0,"上传成功",upload);
        } catch (IOException exception) {
            exception.printStackTrace();
        }

        return new BaseResult(0,"上传失败");
    }





}
